package wang.hex.codetransfer.code;

import java.io.FileNotFoundException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.*;

/**
 * @Author wujie
 * @Class FileReciver
 * @Description
 * @Date 2021/1/6 15:47
 */
public class FileReceiver extends Receiver {
    private static ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4);
    private Set<Long> set = new HashSet<>();
    private String path;
    private long delay = 200;
    private int realLen;

    private long totalPage;
    private FileChannel channel;
    private RandomAccessFile accessFile;
    private boolean stoped = false;

    private ScheduledFuture<?> schedule = null;

    public FileReceiver(int x, int y, int width, int height, int len, long delay) {
        super(x, y, width, height);
        this.realLen = len - 12;
        this.delay = delay;
    }

    public void setFile(String path) {
        this.path = path;


        try {
            accessFile = new RandomAccessFile(path, "rw");
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
        channel = accessFile.getChannel();
    }

    public boolean getStoped() {
        return stoped;
    }

    public void stop() {
        stoped = true;
        if (schedule != null) {
            schedule.cancel(true);
        }
        executorService.shutdown();
    }

    public void start() {
        if (this.path == null) {
            throw new RuntimeException("未设置文件");
        }
        schedule = executorService.scheduleAtFixedRate(() -> {
            try {
                ByteData byteData = doReceive();
                byte[] data = byteData.getData();
                long pageNum = byteData.getPageNum();
                int len = byteData.getLen();
                if (len == -1) {
                    totalPage = pageNum;
                }
                if (!set.contains(pageNum)) {
                    MappedByteBuffer map = channel.map(FileChannel.MapMode.READ_WRITE, pageNum * realLen, data.length);
                    map.put(data);
                    map.force();
                    map.clear();
                    set.add(pageNum);
                }
                System.out.println(data.length + " " + pageNum + "/" + totalPage);
                if (set.size() == totalPage) {
                    channel.close();
                    accessFile.close();
                    System.out.println("stop!!");
                    stop();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }, 0, delay, TimeUnit.MILLISECONDS);
    }

}
